package reflection

import (
	"fmt"
	"reflect"
)

// Person 用于反射演示的结构体
type Person struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}

// SayHello 用于反射演示的方法
func (p Person) SayHello() string {
	return fmt.Sprintf("你好，我是%s，今年%d岁", p.Name, p.Age)
}

// DemoReflectionBasic 演示基本的反射操作
func DemoReflectionBasic() {
	fmt.Println("=== 反射(Reflection)演示 ===")
	fmt.Println("\n--- 基本类型反射 ---")
	
	// 获取变量的类型和值
	var num int = 42
	typeOfNum := reflect.TypeOf(num)
	valueOfNum := reflect.ValueOf(num)
	
	fmt.Printf("变量类型: %v\n", typeOfNum)
	fmt.Printf("变量值: %v\n", valueOfNum)
	fmt.Printf("是否为整数类型: %v\n", valueOfNum.Kind() == reflect.Int)
	
	// 修改可寻址变量的值
	var num2 int = 100
	valueOfNum2 := reflect.ValueOf(&num2).Elem()
	valueOfNum2.SetInt(200)
	fmt.Printf("修改后的num2: %d\n", num2)
}

// DemoReflectionStruct 演示结构体的反射操作
func DemoReflectionStruct() {
	fmt.Println("\n--- 结构体反射 ---")
	
	// 创建一个结构体实例
	person := Person{Name: "张三", Age: 30}
	
	// 获取结构体的类型和值
	typeOfPerson := reflect.TypeOf(person)
	valueOfPerson := reflect.ValueOf(person)
	
	// 打印结构体的字段信息
	fmt.Printf("结构体名称: %s\n", typeOfPerson.Name())
	fmt.Println("结构体字段:")
	for i := 0; i < typeOfPerson.NumField(); i++ {
		field := typeOfPerson.Field(i)
		value := valueOfPerson.Field(i)
		fmt.Printf("  %s (%s): %v\n", field.Name, field.Type, value)
		// 获取标签
		if tag := field.Tag.Get("json"); tag != "" {
			fmt.Printf("  标签(json): %s\n", tag)
		}
	}
}

// DemoReflectionMethod 演示方法的反射调用
func DemoReflectionMethod() {
	fmt.Println("\n--- 方法反射调用 ---")
	
	// 创建一个结构体实例
	person := Person{Name: "李四", Age: 25}
	
	// 获取方法并调用
	valueOfPerson := reflect.ValueOf(person)
	method := valueOfPerson.MethodByName("SayHello")
	if method.IsValid() {
		// 调用方法
		result := method.Call(nil)
		fmt.Printf("方法调用结果: %v\n", result[0])
	} else {
		fmt.Println("未找到SayHello方法")
	}
}

// DemoReflectionFeatures 整合演示所有反射特性
func DemoReflectionFeatures() {
	DemoReflectionBasic()
	DemoReflectionStruct()
	DemoReflectionMethod()
}